/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.designtime.api.increment.extractor;

import com.inspur.edp.cef.designtime.api.changecontrolrule.controlrule.basic.ControlRuleItem;
import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.entity.ControlRuleDefItem;
import com.inspur.edp.cef.designtime.api.changecontrolrule.controlruledef.basic.entity.ControlRuleValue;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.collection.GspEnumValueCollection;
import com.inspur.edp.cef.designtime.api.entity.MappingRelation;
import com.inspur.edp.cef.designtime.api.increment.property.AssoColPropIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.BooleanPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.EnumColIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.IntPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.MappingDicPropIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.ObjectPropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.PropertyIncrement;
import com.inspur.edp.cef.designtime.api.increment.property.StringPropertyIncrement;
import io.iec.edp.caf.commons.exception.CAFRuntimeException;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import java.util.HashMap;
import org.springframework.util.ObjectUtils;

public class ExtractUtils {

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            String oldValue,
            String newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (isEqual(oldValue,newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        StringPropertyIncrement increment = new StringPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            int oldValue,
            int newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue == newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        IntPropertyIncrement increment = new IntPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            boolean oldValue,
            boolean newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue==newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        BooleanPropertyIncrement increment = new BooleanPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            Object oldValue,
            Object newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        ObjectPropertyIncrement increment = new ObjectPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            GspEnumValueCollection oldValue,
            GspEnumValueCollection newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        EnumColIncrement increment = new EnumColIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    public static void extractValue(
            HashMap<String, PropertyIncrement> propChange,
            GspAssociationCollection oldValue,
            GspAssociationCollection newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        AssoColPropIncrement increment = new AssoColPropIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }
    public static void extractValue(
        HashMap<String, PropertyIncrement> propChange,
        MappingRelation oldValue,
        MappingRelation newValue,
        String propName,
        ControlRuleItem rule,
        ControlRuleDefItem ruleDefItem) {
        if (oldValue.equals(newValue))
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;

        MappingDicPropIncrement increment = new MappingDicPropIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }

    private static boolean isAllow(
            String propertyName, Object oldValue, Object newValue, ControlRuleItem rule, ControlRuleDefItem ruleDefItem) {
        if(rule == null && ruleDefItem == null)
            return true;
        if(rule == null)
            return ruleDefItem.getDefaultRuleValue() == ControlRuleValue.Allow;
        switch (rule.getControlRuleValue()) {
            case Allow:
                return true;
            case Forbiddon:
                return false;
            case Default:
                return ruleDefItem.getDefaultRuleValue() == ControlRuleValue.Allow;
            default:
                throw new RuntimeException("没有找到对应的控制方式:"+rule.getControlRuleValue());
        }

    }


    public static void extractValueAllowShort(
            HashMap<String, PropertyIncrement> propChange,
            int oldValue,
            int newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {

        if (oldValue == newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;
        if(newValue > oldValue)
            throw new CAFRuntimeException("", "",
                    "属性"+propName+"的不允许增加", null, ExceptionLevel.Error);

        IntPropertyIncrement increment = new IntPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }


    public static void extractValueAllow2True(
            HashMap<String, PropertyIncrement> propChange,
            boolean oldValue,
            boolean newValue,
            String propName,
            ControlRuleItem rule,
            ControlRuleDefItem ruleDefItem) {

        if (oldValue == newValue)
            return;
        if (!isAllow(propName, oldValue, newValue, rule, ruleDefItem))
            return;
        if(oldValue)
            throw new CAFRuntimeException("", "",
                    "属性"+propName+"的不允许设置为否", null, ExceptionLevel.Error);

        IntPropertyIncrement increment = new IntPropertyIncrement(true);
        increment.setPropertyValue(newValue);
        propChange.put(propName, increment);
    }


    private static boolean isEqual(Object oldValue, Object newValue){
        return ObjectUtils.nullSafeEquals(oldValue, newValue);
    }
}
